//package XMLCreator;
//
//import java.util.Collection;
//import java.util.LinkedList;
//import java.util.Vector;
//
//import Main.Pair;
//
//
//public class WikiParser {
//
//	private int inClosingBraces; // {{ }}
//	private boolean inClosedSquare;// [[ ]]
//	private boolean inTriangularBrackets; //< >
//	private String ans;
//	private int index; 
//	private String text;
//	private int length;
//	private int lineIndex; 
//	private String[] lines;
//	private String thisLineAns;
//	private String subString;
//	private boolean needToFinish;
//	private boolean inRef;
//
//	private void init(){
//		inClosingBraces=0;
//		index=0;
//		lines=text.split("\n");
//		ans="";
//		inClosedSquare=false;
//		inRef=false;
//		needToFinish=false;
//	}
//
//	private void needToFinish(){
//		needToFinish=(lines[lineIndex].startsWith("==External links") | lines[lineIndex].startsWith("==See also") | lines[lineIndex].startsWith("==References") | lines[lineIndex].startsWith("==Notes"));
//	}
//
//	private boolean needToIgnore(char ch){
//		return (ch=='\'' & ((index!=0 && lines[lineIndex].charAt(index-1)=='\'') | (index+1<length && lines[lineIndex].charAt(index+1)=='\''))) |
//		(ch==':' && index==0);
//	}
//
//	private void triangularBracketsHandel(){
//		if (subString.startsWith("ref")){
//			inRef=true;
//		}
//		if (subString.startsWith("/ref")){
//			inRef=false;
//		}		
//	}
//
//	private void closingBracesHandel(){
//		int index1=subString.indexOf('|');
//		if (index1==-1 || subString.indexOf('|', index1+1)==-1)
//			thisLineAns+=subString.substring(index1+1);
//	}
//
//	private void parseChar() {
//		subString="";
//		char ch=lines[lineIndex].charAt(index);
//
//		if (ch=='{' && index+1<length && lines[lineIndex].charAt(index+1)=='{'){
//			index++;
//			inClosingBraces++;
//		}
//		else if (ch=='}' && index+1<length && lines[lineIndex].charAt(index+1)=='}'){
//			index++;
//			inClosingBraces--;	
//		}	
//		else if (inClosingBraces==0){
//			if (ch=='<'){
//				subString="";
//				inTriangularBrackets=true;
//			}
//			else if (ch=='>'){
//				triangularBracketsHandel();
//				inTriangularBrackets=false;
//			}
//			else if (inTriangularBrackets){
//				subString+=ch;
//			}			
//			else if (inRef) 
//			{}
//			else if (ch=='[' && index+1<length && lines[lineIndex].charAt(index+1)=='['){
//				//				if (lines[lineIndex].substring(index).startsWith("[[Category:")){
//				//				}
//				subString="";
//				index++;
//				inClosedSquare=true;
//			}
//			else if (ch==']' && index+1<length && lines[lineIndex].charAt(index+1)==']'){
//				index++;
//				closingBracesHandel();
//				inClosedSquare=false;
//			}
//			else if (inClosedSquare){
//				subString+=ch;
//			}
//			else if (ch=='&' && index+5<length && lines[lineIndex].substring(index,index+6).equals("&nbsp;")){
//				index+=5;
//			}
//			else if (!needToIgnore(ch))
//				thisLineAns+=ch;
//		}
//	}
//
//	public Pair<String,Collection<String>> parse2(String text){
//		this.text=text;
//		init();
//
//		for(lineIndex=0;lineIndex<lines.length;lineIndex++){
//			thisLineAns="";
//			needToFinish();
//			if (needToFinish)
//				break;
//			length=lines[lineIndex].length();
//			for(index=0;index<length;index++){
//				parseChar();
//			}
//			String trim=thisLineAns.trim();
//			if (trim.length()>0)
//				//				System.out.println(trim);//TODO
//				ans+="\n"+trim;
//		}
//
//		LinkedList<String> categories=new LinkedList<String>();
//
//		try {
//			for(int i=0;i<lines.length;i++){
//				String line=lines[i];
//				if (line.startsWith("[[Category:")){
//					int len="[[Category:".length();
//					if (len<0){
//						System.out.println("WikiParser.parse len="+len+" lines["+i+"]="+lines[i]+" lines["+(i+1)+"]="+lines[i+1]);//TODO
//						continue;
//					}
//					if (line.indexOf('|')<0){
//						int len2=line.indexOf("]");
//						if (len2<0){
//							System.out.println("WikiParser.parse len2="+len2+" len="+len+" lines["+i+"]="+lines[i]+" lines["+(i+1)+"]="+lines[i+1]);//TODO
//							continue;
//						}
//						categories.add(line.substring(len,len2).trim());
//					}
//					else{
//						int len2=line.indexOf('|');
//						categories.add(line.substring(len,len2).trim());
//					}
//				}
//			}
//		} catch (Exception e) {
//			System.out.println("WikiParser.parse Exception");//TODO
//			e.printStackTrace();
//		}
//
//		return new Pair<String, Collection<String>>(ans, categories);
//	}
//	
//	public Pair<String,Collection<String>> parse(String text){
//		try {
//			//ans = be.devijver.wikipedia.Parser.toHtml(text, null);
//			
//			be.devijver.wikipedia.SmartLinkResolver smartLinkResolver =
//				   new be.devijver.wikipedia.SmartLinkResolver() {
//				      public String resolve(String smartLink) {
//				         return "";
//				      }
//				   };
//
//				String ans = be.devijver.wikipedia.Parser.toHtml(text, smartLinkResolver);
//			
//			
//
//			String[] lines = text.split("\n");
//			
//			LinkedList<String> categories=new LinkedList<String>();
//
//			try {
//				for(int i=0;i<lines.length;i++){
//					String line=lines[i];
//					if (line.startsWith("[[Category:")){
//						int len="[[Category:".length();
//						if (len<0){
//							System.out.println("WikiParser.parse len="+len+" lines["+i+"]="+lines[i]+" lines["+(i+1)+"]="+lines[i+1]);//TODO
//							continue;
//						}
//						if (line.indexOf('|')<0){
//							int len2=line.indexOf("]");
//							if (len2<0){
//								System.out.println("WikiParser.parse len2="+len2+" len="+len+" lines["+i+"]="+lines[i]+" lines["+(i+1)+"]="+lines[i+1]);//TODO
//								continue;
//							}
//							categories.add(line.substring(len,len2).trim());
//						}
//						else{
//							int len2=line.indexOf('|');
//							categories.add(line.substring(len,len2).trim());
//						}
//					}
//				}
//			} catch (Exception e) {
//				System.out.println("WikiParser.parse Exception");//TODO
//				e.printStackTrace();
//			}
//			ans=ans.replace("<a href=\"\">", "");
//			ans=ans.replace("<\\a>", "");
//			return new Pair<String, Collection<String>>(ans, categories);
//		} catch (Exception e) {
//			return new Pair<String, Collection<String>>("", new Vector<String>());
//		}
//	}
//}


package XMLCreator;

import java.util.Collection;
import java.util.LinkedList;

import Main.Pair;


public class WikiParser {
	
	private int inClosingBraces; // {{ }}
	private boolean inClosedSquare;// [[ ]]
	private boolean inTriangularBrackets; //< >
	private String ans;
	private int index; 
	private String text;
	private int length;
	private int lineIndex; 
	private String[] lines;
	private String thisLineAns;
	private String subString;
	private boolean needToFinish;
	private boolean inRef;
	
	private void init(){
		inClosingBraces=0;
		index=0;
		lines=text.split("\n");
		ans="";
		inClosedSquare=false;
		inRef=false;
		needToFinish=false;
	}
	
	private void needToFinish(){
		needToFinish=(lines[lineIndex].startsWith("==External links") | lines[lineIndex].startsWith("==See also") | lines[lineIndex].startsWith("==References") | lines[lineIndex].startsWith("==Notes"));
	}
	
	private boolean needToIgnore(char ch){
		return (ch=='\'' & ((index!=0 && lines[lineIndex].charAt(index-1)=='\'') | (index+1<length && lines[lineIndex].charAt(index+1)=='\''))) |
		(ch==':' && index==0);
	}
	
	private void triangularBracketsHandel(){
		if (subString.startsWith("ref")){
			inRef=true;
		}
		if (subString.startsWith("/ref")){
			inRef=false;
		}		
	}
	
	private void closingBracesHandel(){
		int index1=subString.indexOf('|');
		if (index1==-1 || subString.indexOf('|', index1+1)==-1)
			thisLineAns+=subString.substring(index1+1);
	}
	
	private void parseChar() {
		char ch=lines[lineIndex].charAt(index);
		
		if (ch=='{' && index+1<length && lines[lineIndex].charAt(index+1)=='{'){
			index++;
			inClosingBraces++;
		}
		else if (ch=='}' && index+1<length && lines[lineIndex].charAt(index+1)=='}'){
			index++;
			inClosingBraces--;	
		}	
		else if (inClosingBraces==0){
			if (ch=='<'){
				subString="";
				inTriangularBrackets=true;
			}
			else if (ch=='>'){
				triangularBracketsHandel();
				inTriangularBrackets=false;
			}
			else if (inTriangularBrackets){
				subString+=ch;
			}			
			else if (inRef) 
			{}
			else if (ch=='[' && index+1<length && lines[lineIndex].charAt(index+1)=='['){
//				if (lines[lineIndex].substring(index).startsWith("[[Category:")){
//				}
				subString="";
				index++;
				inClosedSquare=true;
			}
			else if (ch==']' && index+1<length && lines[lineIndex].charAt(index+1)==']'){
				index++;
				closingBracesHandel();
				inClosedSquare=false;
			}
			else if (inClosedSquare){
				subString+=ch;
			}
			else if (ch=='&' && index+5<length && lines[lineIndex].substring(index,index+6).equals("&nbsp;")){
				index+=5;
			}
			else if (!needToIgnore(ch))
				thisLineAns+=ch;
		}
	}
	
	private boolean isLetterOK(char letter){
		if (letter>='a' & letter<='z')
			return true;
		if (letter>='A' & letter<='Z')
			return true;
		if (letter>='0' & letter<='9')
			return true;
		if (letter==' ' | letter=='\n')
			return true;
		if (letter=='{' | letter=='}' | letter=='<' | letter=='>' | letter=='[' | letter==']' | letter=='(' | letter==')' | letter=='+' | letter=='-' | letter=='=')
			return true;		
		if (letter=='\'' | letter=='\"' | letter==',' | letter=='.' | letter==':' | letter==';' | letter=='!')
			return true;
		if (letter=='#' | letter=='%' | letter=='&' | letter=='@' | letter=='*' | letter=='!' | letter=='?' | letter=='^' | letter=='/' | letter=='\\' | letter=='~' | letter=='_')
			return true;			
		return false;
	}
	
	private String removeTheBadLetter(String text){
		int i=0;
		while(i<text.length()){
			if (isLetterOK(text.charAt(i)))
				i++;
			else
				text=text.replace(text.charAt(i)+"", "?");
		}
		return text;
	}
	
	public Pair<String,Collection<String>> parse(String text){
		this.text=text;
		init();
		
		for(lineIndex=0;lineIndex<lines.length;lineIndex++){
			thisLineAns="";
			needToFinish();
			if (needToFinish)
				break;
			length=lines[lineIndex].length();
			for(index=0;index<length;index++){
				parseChar();
			}
			String trim=thisLineAns.trim();
			
			trim=removeTheBadLetter(trim);

			
			if (trim.length()>0)
//				System.out.println(trim);//TODO
			
				
				ans+="\n"+trim;
		}
		
		LinkedList<String> categories=new LinkedList<String>();
		
		for(int i=0;i<lines.length;i++){
			String line=lines[i];
			if (line.startsWith("[[Category:")){
				int len="[[Category:".length();
				if (line.indexOf('|')<0){
					int len2=line.indexOf("]]");
					categories.add(removeTheBadLetter(line.substring(len,len2).trim()));
				}
				else{
					int len2=line.indexOf('|');
					categories.add(removeTheBadLetter(line.substring(len,len2).trim()));
				}
			}
		}
		
		return new Pair<String, Collection<String>>(ans, categories);
	}
}
